<script setup lang="ts">
import {
  NAutoComplete,
  NButton,
  NCard,
  NDataTable,
  NInput,
  NLayout,
  NLayoutContent,
  NLayoutSider,
  NModal,
  NSpace,
  useDialog,
  useMessage,
} from 'naive-ui'

import {
  computed,
  h,
  onMounted,
  onUnmounted,
  ref,
  watch,
} from 'vue'

import type { DataTableRowKey } from 'naive-ui'
import axios from 'axios'

import type { Ref } from 'vue'
import { useRoute } from 'vue-router'
import { storeToRefs } from 'pinia'
import html2canvas from 'html2canvas'

import { Message } from '../reportChat/components'
import { useScroll } from '../reportChat/hooks/useScroll'
import { useChat } from '../reportChat/hooks/useChat'
import { useUsingContext } from '../reportChat/hooks/useUsingContext'
import HeaderComponent from '../reportChat/components/Header/index.vue'
import {
  ChatLayout,
} from '@/views/chat/layout'
import {
  useChatStore,
  usePromptStore,
} from '@/store'
import { HoverButton, SvgIcon } from '@/components/common'
import { useBasicLayout } from '@/hooks/useBasicLayout'
import { fetchChatAPIProcess } from '@/api'
import { t } from '@/locales'

// 假设每篇文章有一个唯一的ID作为键
interface Article {
  articleId: string
  articleTitle: string
  articleYear: string
  articleAuthors: string
  articleLanguage: string
  articleText: string
  articleUrl: string
  doc_name: string
}
// const articles = ref([]);
const articles = ref<Article[]>([])
const showAbstractModal = ref(false)
const showOutlineModal = ref(false)
const currentAbstract = ref('')
// const searchQuery = ref('');
const searchQuery = ref<string>('')
const checkedRowKeys = ref<DataTableRowKey[]>([])
const selectedArticleIds = ref<string[]>([])
const chatResponse = ref('')
const showCustomDateModal = ref(false)
const dateFilter = ref('')
const startYear = ref(null)
const endYear = ref(null)

// 定义一个响应式变量来存储选中的值
const selectedOption = ref('')

// 定义文章列表正文部分是否展开
const expandedStates = ref<{ [key: string]: boolean }>({})
// 大纲模态框相关

const inputCount = ref(3) // 默认输入框数量为三个
const reportTitle = ref('')
const reportOutlines = ref(new Array(inputCount.value).fill(''))
// const reportOutlines = ref<string[]>([]);

// 定义 columns
const columns = [
  {
    type: 'selection',
    width: '50px',
  },
  {
    key: 'detail',
    width: '100%',
    render(row: Article) {
      // 切换文章展开状态的函数
      const toggleExpand = () => {
        expandedStates.value[row.articleId] = !expandedStates.value[row.articleId]
      }
      return [
        h('div', { style: { color: 'green' } }, `${row.articleTitle}`),
        h('div', {
          style: { display: 'flex', alignItems: 'center', gap: '10px' },
        }, [
          h('div', {
            style: {
              display: 'inline-block',
              padding: '2px 8px',
              borderRadius: '10px',
              backgroundColor: '#f0f0f0',
            },
          }, `${row.articleYear}`),
          h('div', {
            style: {
              display: 'inline-block',
              padding: '2px 8px',
              borderRadius: '10px',
              backgroundColor: '#f0f0f0',
            },
          }, `${row.articleLanguage}`),
          h('div', { style: { color: 'grey' } }, `${row.articleAuthors}`),
        ]),
        // 根据展开状态动态添加或移除 three-line-clamp 类
        h('div', {
          class: { 'three-line-clamp': !expandedStates.value[row.articleText] },
          onClick: toggleExpand,
          style: { cursor: 'pointer' }, // 可选，使其看起来可以点击
        }, `${row.articleText}`),
        h('div', { style: { margin: '10px 0' } }), // 添加间隔的 div 元素
        // h('a', {
        // class: { 'three-line-clamp': !expandedStates.value[row.articleUrl] },
        // onClick: toggleExpand,
        // style: { cursor: 'pointer' }, // 可选，使其看起来可以点击
        // attrs: { href: row.articleUrl },
        // }, `${row.articleUrl}`),
        h('a', { href: row.articleUrl, target: '_blank' }, `${row.doc_name}`),
        // h('div', {}, `${row.articleId}`)
      ]
    },
  },
]

// 为每行定义一个唯一键
const rowKey = (row: Article) => row.articleId

// 处理复选框状态变化
// const handleCheck = (keys: DataTableRowKey[]) => {
//   checkedRowKeys.value = keys;
// };
// 更新选中的文章ID
const handleCheck = (checkedRowKeys: string[]) => {
  selectedArticleIds.value = checkedRowKeys
}

watch(dateFilter, (newValue) => {
  if (newValue === 'custom')
    showCustomDateModal.value = true
})

const searchArticles = async () => {
  try {
    console.log('打印keyWord', searchQuery.value)
    const response = await axios.post('http://localhost:8001/api/query_Intime_Result', {
      query: searchQuery.value,
      doc_type: 'Documentation__meta',
    })
    articles.value = response.data.search
    console.log('result:', response.data)
  }
  catch (error) {
    console.error('Error fetching articles:', error)
    articles.value = []
  }
}

const fetchArticles = async () => {
  try {
    console.log('打印keyWord', searchQuery.value)
    const response = await axios({
      method: 'post',
      // baseURL:'http://10.129.40.245:8080',
      baseURL: 'http://localhost:8001',
      url: '/api/query_Intime_Result',
      data: {
        keyWord: searchQuery.value,
        pageNo: 1,
        pageSize: 10,
      },
    })
    articles.value = response.data
  }
  catch (error) {
    console.error('Error fetching articles:', error)
    articles.value = []
  }
}
// 如果搜索关键词为空则返回所有的文章列表，否则关键词搜索
const filteredArticles = computed(() => {
  if (searchQuery.value)
    return articles.value

  return articles.value.filter(article =>
    article.articleTitle.includes(searchQuery.value),
  )
})

const message = useMessage()

const cancelCallback = () => {
  message.success('Cancel')
}

// const submitCallback = () => {
//   message.success('Submit')
//   console.log('模态框确认生成操作');
//   // 根据需要进行操作，比如console测试
// }

const handleGenerateClick = () => {
  if (selectedOption.value === 'multiple') {
    showOutlineModal.value = true
  }
  else {
    // 这里可以放置“单篇观点抽取”时的逻辑，如果没有则不执行任何操作
    // 例如，显示一个消息或执行特定逻辑
    // message.info('单篇观点抽取逻辑执行');
  }
}

const submitCallback = async () => {
  // 过滤选中的文章，基于过滤后的文章列表
  const selectedArticles = filteredArticles.value.filter(article => selectedArticleIds.value.includes(article.articleId))

  // 准备要发送的数据
  const postData = {
    doc_list: selectedArticles.map(article => ({
      doc_title: article.articleTitle,
      doc_content: article.articleText,
    })),
    user_title: reportTitle.value,
    user_outline: reportOutlines.value,
    user_keywords: '核武器、核态势、全球核武器发展、中国、美国、朝鲜、俄罗斯、中美',
  }

  // 设置请求头
  const config = {
    headers: {
      'Content-Type': 'application/json',
    },
  }

  // 发送POST请求
  try {
    // const response = await axios.post('/api/endpoint', postData);
    // console.log('Submit Success:', response);
    console.log(postData)
    const response = await axios.post('http://10.112.203.120:8017/multi_doc_generate', postData, config)
    // const response = await axios.post('http://10.112.203.120:20618/multi_doc_generate', postData, config);
    console.log('Data submitted successfully:', response.data)
    // 成功后的操作...
  }
  catch (error) {
    console.error('Submit Error:', error)
    console.error('Error submitting data:', error)
    // 错误处理...
  }
}

function decreaseInputCount() {
  if (inputCount.value > 1)
    inputCount.value--
}

function increaseInputCount() {
  inputCount.value++
}
watch(inputCount, (newCount, oldCount) => {
  if (newCount > oldCount) {
    for (let i = oldCount; i < newCount; i++)
      reportOutlines.value.push('')
  }
  else {
    reportOutlines.value = reportOutlines.value.slice(0, newCount)
  }
})

watch(reportOutlines, (newVal) => {
  console.log('reportOutlines changed:', newVal)
})

// chat界面的
let controller = new AbortController()

const openLongReply = import.meta.env.VITE_GLOB_OPEN_LONG_REPLY === 'true'

const route = useRoute()
const dialog = useDialog()
const ms = useMessage()

const chatStore = useChatStore()

const { isMobile } = useBasicLayout()
const { addChat, updateChat, updateChatSome, getChatByUuidAndIndex } = useChat()
const { scrollRef, scrollToBottom, scrollToBottomIfAtBottom } = useScroll()
const { usingContext, toggleUsingContext } = useUsingContext()

const { mode, uuid } = route.params as { mode: string; uuid: string }

const dataSources = computed(() => chatStore.getChatByUuid(+uuid))
const conversationList = computed(() => dataSources.value.filter(item => (!item.inversion && !!item.conversationOptions)))

const prompt = ref<string>('')
const loading = ref<boolean>(false)
const inputRef = ref<Ref | null>(null)

// 添加PromptStore
const promptStore = usePromptStore()

// 使用storeToRefs，保证store修改后，联想部分能够重新渲染
const { promptList: promptTemplate } = storeToRefs<any>(promptStore)

// 未知原因刷新页面，loading 状态不会重置，手动重置
dataSources.value.forEach((item, index) => {
  if (item.loading)
    updateChatSome(+uuid, index, { loading: false })
})

function handleSubmit() {
  onConversation()
}

async function onConversation() {
  const message = prompt.value

  if (loading.value)
    return

  if (!message || message.trim() === '')
    return

  controller = new AbortController()

  addChat(
    mode,
    +uuid,
    {
      dateTime: new Date().toLocaleString(),
      text: message,
      inversion: true,
      error: false,
      conversationOptions: null,
      requestOptions: { prompt: message, options: null },
    },
  )
  scrollToBottom()

  loading.value = true
  prompt.value = ''

  let options: Chat.ConversationRequest = {}
  const lastContext = conversationList.value[conversationList.value.length - 1]?.conversationOptions

  if (lastContext && usingContext.value)
    options = { ...lastContext }

  addChat(
    mode,
    +uuid,
    {
      dateTime: new Date().toLocaleString(),
      text: t('chat.thinking'),
      loading: true,
      inversion: false,
      error: false,
      conversationOptions: null,
      requestOptions: { prompt: message, options: { ...options } },
    },
  )
  scrollToBottom()

  try {
    try {
      console.log('打印keyWord', searchQuery.value)
      const response = await axios.post('http://10.112.203.120:8017/api/query_Intime_Result', {
        // http://localhost:8001/api/query_Intime_Result Documentation__meta CTBTO_time_label http://10.112.203.120:8017/api/query_Intime_Result
        query: searchQuery.value,
        doc_type: 'Documentation__meta',
      })
      articles.value = response.data.search
      chatResponse.value = response.data.result
      // console.log('result:', response.data)
    }
    catch (error) {
      console.error('Error fetching articles:', error)
      articles.value = []
      chatResponse.value = 'Retrun result wrong'
    }
    // const chatResponse = await postChat(message)
    const responseAsString = chatResponse

    updateChat(
      +uuid,
      dataSources.value.length - 1,
      {
        dateTime: new Date().toLocaleString(),
        text: chatResponse.value,
        loading: false,
        inversion: false,
        error: false,
        conversationOptions: null,
        requestOptions: { prompt: message, options: { ...options } },
      },
    )
  }
  catch (error: any) {
    const errorMessage = error?.message ?? t('common.wrong')

    if (error.message === 'canceled') {
      updateChatSome(
        +uuid,
        dataSources.value.length - 1,
        {
          loading: false,
        },
      )
      scrollToBottomIfAtBottom()
      return
    }

    const currentChat = getChatByUuidAndIndex(+uuid, dataSources.value.length - 1)

    if (currentChat?.text && currentChat.text !== '') {
      updateChatSome(
        +uuid,
        dataSources.value.length - 1,
        {
          text: `${currentChat.text}\n[${errorMessage}]`,
          error: false,
          loading: false,
        },
      )
      return
    }
  }
  finally {
    loading.value = false
  }

  updateChat(
    +uuid,
    dataSources.value.length - 1,
    {
      dateTime: new Date().toLocaleString(),
      text: chatResponse.value,
      loading: false,
      inversion: false,
      error: false,
      conversationOptions: null,
      requestOptions: { prompt: message, options: { ...options } },
    },
  )
}

async function onRegenerate(index: number) {
  if (loading.value)
    return

  controller = new AbortController()

  const { requestOptions } = dataSources.value[index]

  let message = requestOptions?.prompt ?? ''

  let options: Chat.ConversationRequest = {}

  if (requestOptions.options)
    options = { ...requestOptions.options }

  loading.value = true

  updateChat(
    +uuid,
    index,
    {
      dateTime: new Date().toLocaleString(),
      text: '',
      inversion: false,
      error: false,
      loading: true,
      conversationOptions: null,
      requestOptions: { prompt: message, options: { ...options } },
    },
  )

  try {
    let lastText = ''
    const fetchChatAPIOnce = async () => {
      await fetchChatAPIProcess<Chat.ConversationResponse>({
        prompt: message,
        options,
        signal: controller.signal,
        onDownloadProgress: ({ event }) => {
          const xhr = event.target
          const { responseText } = xhr
          // Always process the final line
          const lastIndex = responseText.lastIndexOf('\n', responseText.length - 2)
          let chunk = responseText
          if (lastIndex !== -1)
            chunk = responseText.substring(lastIndex)
          try {
            const data = JSON.parse(chunk)
            updateChat(
              +uuid,
              index,
              {
                dateTime: new Date().toLocaleString(),
                text: lastText + (data.text ?? ''),
                inversion: false,
                error: false,
                loading: true,
                conversationOptions: { conversationId: data.conversationId, parentMessageId: data.id },
                requestOptions: { prompt: message, options: { ...options } },
              },
            )

            if (openLongReply && data.detail.choices[0].finish_reason === 'length') {
              options.parentMessageId = data.id
              lastText = data.text
              message = ''
              return fetchChatAPIOnce()
            }
          }
          catch (error) {
            //
          }
        },
      })
      updateChatSome(+uuid, index, { loading: false })
    }
    await fetchChatAPIOnce()
  }
  catch (error: any) {
    if (error.message === 'canceled') {
      updateChatSome(
        +uuid,
        index,
        {
          loading: false,
        },
      )
      return
    }

    const errorMessage = error?.message ?? t('common.wrong')

    updateChat(
      +uuid,
      index,
      {
        dateTime: new Date().toLocaleString(),
        text: errorMessage,
        inversion: false,
        error: true,
        loading: false,
        conversationOptions: null,
        requestOptions: { prompt: message, options: { ...options } },
      },
    )
  }
  finally {
    loading.value = false
  }
}

function handleExport() {
  if (loading.value)
    return

  const d = dialog.warning({
    title: t('chat.exportImage'),
    content: t('chat.exportImageConfirm'),
    positiveText: t('common.yes'),
    negativeText: t('common.no'),
    onPositiveClick: async () => {
      try {
        d.loading = true
        const ele = document.getElementById('image-wrapper')
        const canvas = await html2canvas(ele as HTMLDivElement, {
          useCORS: true,
        })
        const imgUrl = canvas.toDataURL('image/png')
        const tempLink = document.createElement('a')
        tempLink.style.display = 'none'
        tempLink.href = imgUrl
        tempLink.setAttribute('download', 'chat-shot.png')
        if (typeof tempLink.download === 'undefined')
          tempLink.setAttribute('target', '_blank')

        document.body.appendChild(tempLink)
        tempLink.click()
        document.body.removeChild(tempLink)
        window.URL.revokeObjectURL(imgUrl)
        d.loading = false
        ms.success(t('chat.exportSuccess'))
        Promise.resolve()
      }
      catch (error: any) {
        ms.error(t('chat.exportFailed'))
      }
      finally {
        d.loading = false
      }
    },
  })
}

function handleDelete(index: number) {
  if (loading.value)
    return

  dialog.warning({
    title: t('chat.deleteMessage'),
    content: t('chat.deleteMessageConfirm'),
    positiveText: t('common.yes'),
    negativeText: t('common.no'),
    onPositiveClick: () => {
      chatStore.deleteChatByUuid(+uuid, index)
    },
  })
}

function handleClear() {
  if (loading.value)
    return

  dialog.warning({
    title: t('chat.clearChat'),
    content: t('chat.clearChatConfirm'),
    positiveText: t('common.yes'),
    negativeText: t('common.no'),
    onPositiveClick: () => {
      chatStore.clearChatByUuid(+uuid)
    },
  })
}

function handleEnter(event: KeyboardEvent) {
  if (!isMobile.value) {
    if (event.key === 'Enter' && !event.shiftKey) {
      event.preventDefault()
      handleSubmit()
    }
  }
  else {
    if (event.key === 'Enter' && event.ctrlKey) {
      event.preventDefault()
      handleSubmit()
    }
  }
}

function handleStop() {
  if (loading.value) {
    controller.abort()
    loading.value = false
  }
}

// 可优化部分
// 搜索选项计算，这里使用value作为索引项，所以当出现重复value时渲染异常(多项同时出现选中效果)
// 理想状态下其实应该是key作为索引项,但官方的renderOption会出现问题，所以就需要value反renderLabel实现
const searchOptions = computed(() => {
  if (prompt.value.startsWith('/')) {
    return promptTemplate.value.filter((item: { key: string }) => item.key.toLowerCase().includes(prompt.value.substring(1).toLowerCase())).map((obj: { value: any }) => {
      return {
        label: obj.value,
        value: obj.value,
      }
    })
  }
  else {
    return []
  }
})

// value反渲染key
const renderOption = (option: { label: string }) => {
  for (const i of promptTemplate.value) {
    if (i.value === option.label)
      return [i.key]
  }
  return []
}

const placeholder = computed(() => {
  if (isMobile.value)
    return t('chat.placeholderMobile')
  return t('chat.placeholder')
})

const buttonDisabled = computed(() => {
  return loading.value || !prompt.value || prompt.value.trim() === '' || uuid == ''
})

const footerClass = computed(() => {
  let classes = ['p-4']
  if (isMobile.value)
    classes = ['sticky', 'left-0', 'bottom-0', 'right-0', 'p-2', 'pr-3', 'overflow-hidden']
  return classes
})

onMounted(() => {
  scrollToBottom()
  if (inputRef.value && !isMobile.value)
    inputRef.value?.focus()
})

onUnmounted(() => {
  if (loading.value)
    controller.abort()
})

const fileSrc = computed(() => chatStore.getFileSrcByUuid(+uuid))

function chatDivStyle() {
  if (fileSrc.value != null)
    return 'grid grid-cols-2 w-full h-full overflow-hidden'

  else
    return 'grid w-full h-full overflow-hidden'
}
</script>

<template>
  <NLayoutSider width="50%">
    <NLayout>
      <!-- 搜索框 -->
      <!-- <NLayoutHeader> -->
      <!-- <NCard> -->
      <!-- <div class="flex items-center justify-between space-x-2"> -->
      <!-- <NInput v-model:value="searchQuery" placeholder="请输入RAG查询语句" class="input-with-select" /> -->
      <!-- <NButton type="primary" @click="searchArticles"> -->
      <!-- <template #icon> -->
      <!-- <SvgIcon icon="ri:search-line" /> -->
      <!-- </template> -->
      <!-- </NButton> -->
      <!-- </div> -->
      <!-- </NCard> -->
      <!-- </NLayoutHeader> -->
      <NLayout has-sider>
        <NLayoutContent>
          <NCard>
            <div class="flex items-center justify-end space-x-2">
              <NSelect v-model:value="selectedOption" style="width: 30%" :options="options" />
              <NButton type="primary" @click="handleGenerateClick">
                <template #icon>
                  <!-- SvgIcon或其他图标 -->
                  <a>生成</a>
                </template>
              </NButton>
            </div>

            <!-- <NModal v-model:show="showOutlineModal" preset="dialog" title="报告大纲生成" positive-text="确认生成" negative-text="取消" @positive-click="submitCallback" @negative-click="cancelCallback" @submitOutline="handleOutlineSubmit" style="width: 30%"> <OutlineGeneration @closeModal="showOutlineModal = false" /> </NModal> -->
            <NModal
              v-model:show="showOutlineModal" preset="dialog" title="报告大纲生成" positive-text="确认生成"
              negative-text="取消" style="width: 30%" @positive-click="submitCallback" @negative-click="cancelCallback"
            >
              <!-- <OutlineGeneration @closeModal="showOutlineModal = false" /> -->
              <NCard>
                <NSpace vertical>
                  <div>请输入报告标题</div>
                  <NInput v-model:value="reportTitle" type="text" placeholder="请输入报告标题" />
                  <NSpace>
                    <div>可修改增删大纲</div>
                    <!-- “减”按钮 -->
                    <NButton @click="decreaseInputCount">
                      -
                    </NButton>
                    <!-- “加”按钮 -->
                    <NButton @click="increaseInputCount">
                      +
                    </NButton>
                  </NSpace>

                  <!-- 使用 v-for 根据 inputCount 动态生成输入框 -->
                  <NInput
                    v-for="index in inputCount" :key="index" v-model:value="reportOutlines[index - 1]" type="text"
                    placeholder="请输入报告大纲内容" clearable
                  />
                </NSpace>
              </NCard>
            </NModal>
          </NCard>

          <!-- 文章列表 -->
          <!-- 文章列表表格 -->
          <NCard>
            <!-- <div>共检索出6篇文章</div> -->

            <NDataTable
              :columns="columns" :data="filteredArticles" :row-key="rowKey"
              @update:checked-row-keys="handleCheck"
            />
          </NCard>
        </NLayoutContent>
      </NLayout>
    </NLayout>
    <!-- 摘要弹窗 -->
    <NModal v-model:show="showAbstractModal" title="文章摘要" :width="600">
      <NCard style="width: 600px" title="文章摘要" :bordered="false" size="huge" role="dialog" aria-modal="true">
        <p>{{ currentAbstract }}</p>
        <template #footer>
          <NSpace>
            <NButton type="primary" @click="showAbstractModal = false">
              关闭
            </NButton>
          </NSpace>
        </template>
      </NCard>
    </NModal>
  </NLayoutSider>
  <NLayoutContent>
    <!-- <ReportChatView></ReportChatView> -->
    <ChatLayout>
      <div class="flex flex-col w-full h-full">
        <HeaderComponent
          v-if="isMobile" :using-context="usingContext" @export="handleExport"
          @handle-clear="handleClear"
        />
        <div :class="chatDivStyle()">
          <main class="flex-1 overflow-hidden">
            <div id="scrollRef" ref="scrollRef" class="h-full overflow-hidden overflow-y-auto">
              <div
                id="image-wrapper" class="w-full max-w-screen-xl m-auto dark:bg-[#101014]"
                :class="[isMobile ? 'p-2' : 'p-4']"
              >
                <template v-if="!dataSources.length">
                  <div class="flex items-center justify-center mt-4 text-center text-neutral-300">
                    <SvgIcon icon="ri:bubble-chart-fill" class="mr-2 text-3xl" />
                    <span>{{ t('chat.newChatTitle') }}</span>
                  </div>
                </template>
                <template v-else>
                  <div>
                    <Message
                      v-for="(item, index) of dataSources" :key="index" :date-time="item.dateTime"
                      :text="item.text" :inversion="item.inversion" :error="item.error" :loading="item.loading"
                      @regenerate="onRegenerate(index)" @delete="handleDelete(index)"
                    />
                    <div class="sticky bottom-0 left-0 flex justify-center">
                      <NButton v-if="loading" type="warning" @click="handleStop">
                        <template #icon>
                          <SvgIcon icon="ri:stop-circle-line" />
                        </template>
                        {{ t('common.stopResponding') }}
                      </NButton>
                    </div>
                  </div>
                </template>
              </div>
            </div>
          </main>
          <div v-if="fileSrc != null">
            <iframe class="w-full h-full" :src="fileSrc" />
          </div>
        </div>
        <footer :class="footerClass">
          <!-- <div class="w-full max-w-screen-xl m-auto"> -->
          <div class="flex items-center justify-between space-x-2">
            <HoverButton v-if="!isMobile" @click="handleClear">
              <span class="text-xl text-[#4f555e] dark:text-white">
                <SvgIcon icon="ri:delete-bin-line" />
              </span>
            </HoverButton>
            <HoverButton v-if="!isMobile" @click="handleExport">
              <span class="text-xl text-[#4f555e] dark:text-white">
                <SvgIcon icon="ri:download-2-line" />
              </span>
            </HoverButton>
            <HoverButton @click="toggleUsingContext">
              <span class="text-xl" :class="{ 'text-[#4b9e5f]': usingContext, 'text-[#a8071a]': !usingContext }">
                <SvgIcon icon="ri:chat-history-line" />
              </span>
            </HoverButton>
            <NAutoComplete v-model:value="prompt" :options="searchOptions" :render-label="renderOption">
              <template #default="{ handleInput, handleBlur, handleFocus }">
                <NInput
                  ref="inputRef" v-model:value="searchQuery" type="textarea" :placeholder="placeholder"
                  :autosize="{ minRows: 1, maxRows: isMobile ? 4 : 8 }" @input="handleInput" @focus="handleFocus"
                  @blur="handleBlur" @keypress="handleEnter"
                />
              </template>
            </NAutoComplete>
            <NButton type="primary" :disabled="buttonDisabled" @click="handleSubmit">
              <template #icon>
                <span class="dark:text-black">
                  <SvgIcon icon="ri:send-plane-fill" />
                </span>
              </template>
            </NButton>
          </div>
          <!-- </div> -->
        </footer>
      </div>
    </ChatLayout>
  </NLayoutContent>
</template>

<style scoped>
/* 限制文本显示为三行 */
.three-line-clamp {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}
</style>
